package com.oop.example.work.bel;

import com.oop.example.xml.Homonym;
import com.oop.example.xml.ObjectFactory;
import com.oop.example.xml.Block;
import com.oop.example.xml.PhraseWithAttribs;
import com.oop.example.xml.Entry;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Marshaller;

/**
 *
 * @author -
 */
public class ParsedEntry {

    private static int homonyms = 0;
    private static int homographs = 0;
    private Entry entry = null;
    private ObjectFactory factory = new ObjectFactory();

    public Entry getEntry() {
        return entry;
    }

    public ParsedEntry(Entry entry) {
        this.entry = entry;
    }

    private class Header {

        public Header(String h, String asn) {
            this.h = h;//(h == null ? h : h.trim());
            this.asn = (asn == null ? "" : asn.trim());
        }
        private String h;
        private String asn;

        @Override
        public String toString() {
            return h + "|" + asn;
        }
    }

    private Header getFirstHeader(Entry entry) {
        List<Entry.Heading.Vocable> vocables = entry.getHeading().getVocable();
        for (Entry.Heading.Vocable v : vocables) {
            List<Entry.Heading.Vocable.Part> parts = v.getPart();
            for (Entry.Heading.Vocable.Part p : parts) {
                List<JAXBElement<?>> partChildren = p.getPartChildren();
                for (JAXBElement<?> el : partChildren) {
                    if (el.getValue() instanceof Block) {
                        Block block = (Block) el.getValue();
                        String asn = block.getAccentSymbolNumber();
                        String h = block.getValue();
                        return new Header(h, asn);
                    }
                }
            }
        }
        throw new IllegalArgumentException("Нет шапки");
    }

    public boolean isHomonym(ParsedEntry other) {
        Header thisHeader = getFirstHeader(entry);
        Header otherHeader = getFirstHeader(other.entry);
        return (thisHeader.asn.equals(otherHeader.asn))
                && thisHeader.h.equals(otherHeader.h);
    }

    public boolean isHomograph(ParsedEntry other) {
        Header thisHeader = getFirstHeader(entry);
        Header otherHeader = getFirstHeader(other.entry);
        return !(thisHeader.asn.equals(otherHeader.asn))
                && thisHeader.h.equals(otherHeader.h);
    }
    private static String[] homonymNumeration = {"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X"};

    public void insertHomonym(ParsedEntry homonym) {

        int countOfExisting = 0;
        //Определяем индекс добавляемого омонима в исходной статье
        for (JAXBElement<?> o : entry.getContent().getClassifierOrPronunciationOrHomonym()) {
            if (o.getValue() instanceof Homonym) {
                countOfExisting++;
            }
        }
        //Добавляем новый(ые) омоним
        for (JAXBElement<?> o : homonym.getEntry().getContent().getClassifierOrPronunciationOrHomonym()) {
            if (o.getValue() instanceof Homonym) {
                Homonym added = (Homonym) o.getValue();
                String newNumerator = homonymNumeration[countOfExisting];

                added.setNumerator(newNumerator);
                entry.getContent().getClassifierOrPronunciationOrHomonym().add(factory.createEntryContentHomonym(added));
                countOfExisting++;
            }
        }
        try {
            homonyms++;
            Header hhh = getFirstHeader(entry);
            System.out.print("" + homonyms + " Homonym " + hhh.h + " -> ");
            JAXBContext ctx = JAXBContext.newInstance(com.oop.example.xml.Entry.class);
            Marshaller marshaller = ctx.createMarshaller();
            //marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(entry, System.out);
            System.out.println();
        } catch (Exception ex) {
            ex.printStackTrace(System.out);
        }
    }

    public void insertHomograph(ParsedEntry homograph) {
        //System.out.println("Add new homograph +-> ");
        int countOfExisting = 0;
        //Определяем индекс добавляемого омонима в исходной статье
        for (JAXBElement<?> o : entry.getContent().getClassifierOrPronunciationOrHomonym()) {
            if (o.getValue() instanceof Homonym) {
                countOfExisting++;
            }
        }

        Header h = null;
        //Удаляем ударение из заголовка!!!
        List<Entry.Heading.Vocable> vocables = entry.getHeading().getVocable();
        for (Entry.Heading.Vocable v : vocables) {
            List<Entry.Heading.Vocable.Part> parts = v.getPart();
            for (Entry.Heading.Vocable.Part p : parts) {
                List<JAXBElement<?>> partChildren = p.getPartChildren();
                for (JAXBElement<?> el : partChildren) {
                    if (el.getValue() instanceof Block) {
                        Block block = (Block) el.getValue();
                        String header = block.getValue();
                        String accentSymbolNumber = block.getAccentSymbolNumber();
                        //Замена элемента
                        //block = factory.createBlock();
                        //block.setValue(header);
                        //------
                        if (accentSymbolNumber != null) {
                            h = new Header(header, accentSymbolNumber);
                            List<JAXBElement<?>> hmonyms = entry.getContent().getClassifierOrPronunciationOrHomonym();
                            for (JAXBElement<?> hom : hmonyms) {
                                if (hom.getValue() instanceof Homonym) {
                                    Homonym homonym = (Homonym) hom.getValue();
                                    Block b = new Block();
                                    b.setValue(header);
                                    b.setAccentSymbolNumber(accentSymbolNumber);
                                    JAXBElement<Block> createPhraseSimple = factory.createPhraseSimple(b);
                                    PhraseWithAttribs phraseWithAttribs = factory.createPhraseWithAttribs();
                                    phraseWithAttribs.getPhraseChildren().add(createPhraseSimple);
                                    homonym.getPronunciationOrClassifierOrTranslation().add(0, factory.createHomonymClassifier(phraseWithAttribs));
                                }
                            }
                        }
                        block.setAccentSymbolNumber(null);
                        //System.out.println("Remove AccentSymbol entry header " + h);
                    }
                }
            }
        }

        //Добавляем новый(ые) омоним
        for (JAXBElement<?> o : homograph.getEntry().getContent().getClassifierOrPronunciationOrHomonym()) {
            if (o.getValue() instanceof Homonym) {
                Homonym added = (Homonym) o.getValue();
                String newNumerator = homonymNumeration[countOfExisting];
                added.setNumerator(newNumerator);
                entry.getContent().getClassifierOrPronunciationOrHomonym().add(factory.createEntryContentHomonym(added));

                Header hh = getFirstHeader(homograph.entry);
                String header = hh.h;
                String accentSymbolNumber = hh.asn;

                Block b = new Block();
                b.setValue(header);
                b.setAccentSymbolNumber(accentSymbolNumber);
                JAXBElement<Block> createPhraseSimple = factory.createPhraseSimple(b);
                PhraseWithAttribs phraseWithAttribs = factory.createPhraseWithAttribs();
                phraseWithAttribs.getPhraseChildren().add(createPhraseSimple);
                added.getPronunciationOrClassifierOrTranslation().add(0, factory.createHomonymClassifier(phraseWithAttribs));


                countOfExisting++;
            }
        }
        try {
            homographs++;
            Header hhh = getFirstHeader(entry);
            System.out.print("" + homographs + " Homograph " + hhh.h + " -> ");
            JAXBContext ctx = JAXBContext.newInstance(com.oop.example.xml.Entry.class);
            Marshaller marshaller = ctx.createMarshaller();
            //marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(entry, System.out);
            System.out.println();
        } catch (Exception ex) {
            ex.printStackTrace(System.out);
        }
    }

    public static void main(String[] args) {
        ParsedEntrys list = new ParsedEntrys();
        List<Entry> entrys = new ArrayList<Entry>();
        for (Entry e : entrys) {
            ParsedEntry pe = new ParsedEntry(e);
            ParsedEntry homograph = list.getHomograph(pe);

            if (homograph != null) {
                homograph.insertHomonym(pe);
            } else {
                ParsedEntry homonym = list.getHomonym(pe);
                if (homonym != null) {
                    homonym.insertHomonym(pe);
                } else {
                    list.add(pe);
                }
            }
        }
    }
}
